{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Export variance contributed by different sources"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import the libraries\n",
    "import ee\n",
    "import pandas as pd\n",
    "import os\n",
    "import numpy as np\n",
    "import random\n",
    "from random import sample\n",
    "import itertools \n",
    "import geopandas as gpd\n",
    "from sklearn.metrics import r2_score\n",
    "from termcolor import colored # this is allocate colour and fonts type for the print title and text\n",
    "from IPython.display import display, HTML"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [],
   "source": [
    "#set the working directory of local drive for Grid search result table loading\n",
    "# os.getcwd()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [],
   "source": [
    "# initialize the earth engine API\n",
    "ee.Initialize()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1 Load the required composites, images and settings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "#definet the color pallette\n",
    "vibgYOR = ['330044', '220066', '1133cc', '33dd00', 'ffda21', 'ff6622', 'd10000']\n",
    "compositeImage =ee.Image(\"users/leonidmoore/ForestBiomass/20200915_Forest_Biomass_Predictors_Image\")\n",
    "compositeImageNew = ee.Image(\"projects/crowtherlab/Composite/CrowtherLab_Composite_30ArcSec\");\n",
    "unboundedGeo = ee.Geometry.Polygon([-180, 88, 0, 88, 180, 88, 180, -88, 0, -88, -180, -88], None, False)\n",
    "# generete the pixel area map\n",
    "pixelArea = ee.Image.pixelArea().divide(10000) # to ha unit\n",
    "# load the biome layer\n",
    "biomeLayer = compositeImage.select(\"WWF_Biome\")\n",
    "biomeMask = biomeLayer.mask(biomeLayer.neq(98)).mask(biomeLayer.neq(99)).gt(0)\n",
    "# load the mean maps for present and potential\n",
    "# load the carbon concentration map\n",
    "carbonConcentration = ee.Image(\"users/leonidmoore/ForestBiomass/Biome_level_Wood_Carbon_Conentration_Map\")\n",
    "# load the biomass density layers\n",
    "mergedAGB_PresentMean = ee.Image(\"users/leonidmoore/ForestBiomass/GroundSourcedModel/EnsambledMaps/Predicted_GS1_MaxScaler_Present_density_Ensambled_Mean_20230427\").unmask() \n",
    "mergedAGB_PotentialMean =  ee.Image(\"users/leonidmoore/ForestBiomass/GroundSourcedModel/EnsambledMaps/Predicted_GS1_MaxScaler_Potential_density_Ensambled_Mean_20230427\").unmask()\n",
    "# define the standardized projection\n",
    "stdProj = mergedAGB_PresentMean.projection()\n",
    "# load the two forest cover layer for existing and potential forest\n",
    "presentForestCover = compositeImage.select('PresentTreeCover').unmask()# make sure it's in  0-1 scale\n",
    "potentialForestCover = ee.Image(\"users/leonidmoore/ForestBiomass/Bastin_et_al_2019_Potential_Forest_Cover_Adjusted\").unmask() # make sure it's in  0-1 scale\n",
    "\n",
    "# define the present and potential forest cover masks\n",
    "presentMask = presentForestCover.gt(0)\n",
    "potentialMask = potentialForestCover.gt(0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "# # load the carbon density layers\n",
    "# SandermannCarbonDiff = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU\").unmask()\n",
    "# SandermannCarbonPresent = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_1km_Present\").unmask()\n",
    "\n",
    "# # mask the diffrence layer\n",
    "# SandermannCarbonLoss = SandermannCarbonDiff.multiply(SandermannCarbonDiff.gt(0))\n",
    "\n",
    "# # load the present and potential forest cover\n",
    "# presentForestCover = compositeImage.select('PresentTreeCover').unmask() # uniform with potential in the  0-1 scale\n",
    "# potentialCoverAdjusted = ee.Image(\"users/leonidmoore/ForestBiomass/Bastin_et_al_2019_Potential_Forest_Cover_Adjusted\").unmask().rename('PotentialForestCover')\n",
    "# # define the present and potential forest cover masks\n",
    "# presentMask = presentForestCover.gt(0)\n",
    "# potentialMask = potentialCoverAdjusted.gte(0.1)\n",
    "\n",
    "# # calculate the sum of the potential in soil with the consideration of forest cover\n",
    "# SandermannCarbonStockLoss = SandermannCarbonLoss.multiply(pixelArea).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "\n",
    "# # add the soil into the PGB as the total potential\n",
    "# potentialTotal_Abs = potentialPGB_Abs.add(SandermannCarbonStockLoss)\n",
    "# # compose those bands into an image\n",
    "# lowerUpperImage = presentAGB_Lower_Abs.rename('preAGB_Lower').addBands(presentAGB_Upper_Abs.rename('preAGB_Upper')).addBands(potentialAGB_Lower_Abs.rename('potAGB_Lower')).addBands(potentialAGB_Upper_Abs.rename('potAGB_Upper')).addBands(presentRoot_Lower_Abs.rename('preRoot_Lower')).addBands(presentRoot_Upper_Abs.rename('preRoot_Upper')).addBands(potentialRoot_Lower_Abs.rename('potRoot_Lower')).addBands(potentialRoot_Upper_Abs.rename('potRoot_Upper')).addBands(presentLitter_Lower_Abs.rename('preLitter_Lower')).addBands(presentLitter_Upper_Abs.rename('preLitter_Upper')).addBands(potentialLitter_Lower_Abs.rename('potLitter_Lower')).addBands(potentialLitter_Upper_Abs.rename('potLitter_Upper')).addBands(potentialTotal_Abs.rename('PotentialTotal'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 Load the images of the uncertainties"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the images with uncertainty\n",
    "GS1_MaxScaler_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/GS1_MaxScaler_Lower_Upper_Map')\n",
    "GS1_MeanScaler_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/GS1_MeanScaler_Lower_Upper_Map')\n",
    "\n",
    "GS2_MaxScaler_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/GS2_MaxScaler_Lower_Upper_Map')\n",
    "GS2_MeanScaler_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/GS2_MeanScaler_Lower_Upper_Map')\n",
    "\n",
    "HM1_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/HM1_Lower_Upper_Map')\n",
    "HM2_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/HM2_Lower_Upper_Map')\n",
    "\n",
    "SD1_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/SD1_Lower_Upper_Map')\n",
    "SD2_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/SD2_Lower_Upper_Map')\n",
    "\n",
    "WK1_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/WK1_Lower_Upper_Map')\n",
    "WK2_Image = ee.Image('users/leonidmoore/ForestBiomass/UncertaintyFigure/WK2_Lower_Upper_Map')\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 Calculate the uncertianty range maps"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [],
   "source": [
    "# this is the AGB range\n",
    "GS1_MaxScaler_AGB_Range = GS1_MaxScaler_Image.select('potAGB_Upper').subtract(GS1_MaxScaler_Image.select('potAGB_Lower'))\n",
    "GS1_MeanScaler_AGB_Range = GS1_MeanScaler_Image.select('potAGB_Upper').subtract(GS1_MeanScaler_Image.select('potAGB_Lower'))\n",
    "\n",
    "GS2_MaxScaler_AGB_Range = GS2_MaxScaler_Image.select('potAGB_Upper').subtract(GS2_MaxScaler_Image.select('potAGB_Lower'))\n",
    "GS2_MeanScaler_AGB_Range = GS2_MeanScaler_Image.select('potAGB_Upper').subtract(GS2_MeanScaler_Image.select('potAGB_Lower'))\n",
    "\n",
    "HM1_AGB_Range = HM1_Image.select('potAGB_Upper').subtract(HM1_Image.select('potAGB_Lower'))\n",
    "HM2_AGB_Range = HM2_Image.select('potAGB_Upper').subtract(HM2_Image.select('potAGB_Lower'))\n",
    "\n",
    "SD1_AGB_Range = SD1_Image.select('potAGB_Upper').subtract(SD1_Image.select('potAGB_Lower'))\n",
    "SD2_AGB_Range = SD2_Image.select('potAGB_Upper').subtract(SD2_Image.select('potAGB_Lower'))\n",
    "\n",
    "WK1_AGB_Range = WK1_Image.select('potAGB_Upper').subtract(WK1_Image.select('potAGB_Lower'))\n",
    "WK2_AGB_Range = WK2_Image.select('potAGB_Upper').subtract(WK2_Image.select('potAGB_Lower'))\n",
    "\n",
    "GS_AGB_Range = GS1_MaxScaler_AGB_Range.add(GS2_MaxScaler_AGB_Range).add(GS1_MeanScaler_AGB_Range).add(GS2_MeanScaler_AGB_Range).divide(4)\n",
    "RM_AGB_Range = HM1_AGB_Range.add(HM2_AGB_Range).add(SD1_AGB_Range).add(SD2_AGB_Range).add(WK1_AGB_Range).add(WK2_AGB_Range).divide(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is the root carbon stock range\n",
    "GS1_MaxScaler_Root_Range = GS1_MaxScaler_Image.select('potRoot_Upper').subtract(GS1_MaxScaler_Image.select('potRoot_Lower'))\n",
    "GS1_MeanScaler_Root_Range = GS1_MeanScaler_Image.select('potRoot_Upper').subtract(GS1_MeanScaler_Image.select('potRoot_Lower'))\n",
    "\n",
    "GS2_MaxScaler_Root_Range = GS2_MaxScaler_Image.select('potRoot_Upper').subtract(GS2_MaxScaler_Image.select('potRoot_Lower'))\n",
    "GS2_MeanScaler_Root_Range = GS2_MeanScaler_Image.select('potRoot_Upper').subtract(GS2_MeanScaler_Image.select('potRoot_Lower'))\n",
    "\n",
    "HM1_Root_Range = HM1_Image.select('potRoot_Upper').subtract(HM1_Image.select('potRoot_Lower'))\n",
    "HM2_Root_Range = HM2_Image.select('potRoot_Upper').subtract(HM2_Image.select('potRoot_Lower'))\n",
    "\n",
    "SD1_Root_Range = SD1_Image.select('potRoot_Upper').subtract(SD1_Image.select('potRoot_Lower'))\n",
    "SD2_Root_Range = SD2_Image.select('potRoot_Upper').subtract(SD2_Image.select('potRoot_Lower'))\n",
    "\n",
    "WK1_Root_Range = WK1_Image.select('potRoot_Upper').subtract(WK1_Image.select('potRoot_Lower'))\n",
    "WK2_Root_Range = WK2_Image.select('potRoot_Upper').subtract(WK2_Image.select('potRoot_Lower'))\n",
    "\n",
    "GS_Root_Range = GS1_MaxScaler_Root_Range.add(GS2_MaxScaler_Root_Range).add(GS1_MeanScaler_Root_Range).add(GS2_MeanScaler_Root_Range).divide(4)\n",
    "RM_Root_Range = HM1_Root_Range.add(HM2_Root_Range).add(SD1_Root_Range).add(SD2_Root_Range).add(WK1_Root_Range).add(WK2_Root_Range).divide(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "# This is the Litter carbon stock range\n",
    "GS1_MaxScaler_Litter_Range = GS1_MaxScaler_Image.select('potLitter_Upper').subtract(GS1_MaxScaler_Image.select('potLitter_Lower'))\n",
    "GS1_MeanScaler_Litter_Range = GS1_MeanScaler_Image.select('potLitter_Upper').subtract(GS1_MeanScaler_Image.select('potLitter_Lower'))\n",
    "\n",
    "GS2_MaxScaler_Litter_Range = GS2_MaxScaler_Image.select('potLitter_Upper').subtract(GS2_MaxScaler_Image.select('potLitter_Lower'))\n",
    "GS2_MeanScaler_Litter_Range = GS2_MeanScaler_Image.select('potLitter_Upper').subtract(GS2_MeanScaler_Image.select('potLitter_Lower'))\n",
    "\n",
    "HM1_Litter_Range = HM1_Image.select('potLitter_Upper').subtract(HM1_Image.select('potLitter_Lower'))\n",
    "HM2_Litter_Range = HM2_Image.select('potLitter_Upper').subtract(HM2_Image.select('potLitter_Lower'))\n",
    "\n",
    "SD1_Litter_Range = SD1_Image.select('potLitter_Upper').subtract(SD1_Image.select('potLitter_Lower'))\n",
    "SD2_Litter_Range = SD2_Image.select('potLitter_Upper').subtract(SD2_Image.select('potLitter_Lower'))\n",
    "\n",
    "WK1_Litter_Range = WK1_Image.select('potLitter_Upper').subtract(WK1_Image.select('potLitter_Lower'))\n",
    "WK2_Litter_Range = WK2_Image.select('potLitter_Upper').subtract(WK2_Image.select('potLitter_Lower'))\n",
    "\n",
    "GS_Litter_Range = GS1_MaxScaler_Litter_Range.add(GS2_MaxScaler_Litter_Range).add(GS1_MeanScaler_Litter_Range).add(GS2_MeanScaler_Litter_Range).divide(4)\n",
    "RM_Litter_Range = HM1_Litter_Range.add(HM2_Litter_Range).add(SD1_Litter_Range).add(SD2_Litter_Range).add(WK1_Litter_Range).add(WK2_Litter_Range).divide(6)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [],
   "source": [
    "SandermannCarbonLossLower = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU_Lower\").unmask()\n",
    "SandermannCarbonLossUpper = ee.Image(\"users/leonidmoore/ForestBiomass/SoilOrganicCarbonModel/SOCS_0_200cm_Diff_1km_Present_subtract_NoLU_Upper\").unmask()\n",
    "# load the present and potential forest cover\n",
    "presentForestCover = compositeImage.select('PresentTreeCover').unmask() # uniform with potential in the  0-1 scale\n",
    "potentialCoverAdjusted = ee.Image(\"users/leonidmoore/ForestBiomass/Bastin_et_al_2019_Potential_Forest_Cover_Adjusted\").unmask().rename('PotentialForestCover')\n",
    "# define the present and potential forest cover masks\n",
    "presentMask = presentForestCover.gt(0)\n",
    "potentialMask = potentialCoverAdjusted.gte(0.1)\n",
    "\n",
    "soilLower = SandermannCarbonLossLower.multiply(pixelArea).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "SoilUpper = SandermannCarbonLossUpper.multiply(pixelArea).divide(1000000000).mask(biomeMask).mask(potentialMask).multiply(potentialCoverAdjusted)\n",
    "\n",
    "Soil_Range = SoilUpper.subtract(soilLower)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate the pixel level model type uncertainty range\n",
    "GS_Model1_Total = GS1_MaxScaler_Image.select('PotentialTotal').add(GS1_MeanScaler_Image.select('PotentialTotal')).divide(2)\n",
    "GS_Model2_Total = GS2_MaxScaler_Image.select('PotentialTotal').add(GS2_MeanScaler_Image.select('PotentialTotal')).divide(2)\n",
    "GS_Model_Range = GS_Model1_Total.subtract(GS_Model2_Total).abs() # abs to get the range \n",
    "\n",
    "RM_Model1_Total = HM1_Image.select('PotentialTotal').add(SD1_Image.select('PotentialTotal')).add(WK1_Image.select('PotentialTotal')).divide(3)\n",
    "RM_Model2_Total = HM2_Image.select('PotentialTotal').add(SD2_Image.select('PotentialTotal')).add(WK2_Image.select('PotentialTotal')).divide(3)\n",
    "RM_Model_Range = RM_Model1_Total.subtract(RM_Model2_Total).abs()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "# calculate the pixel level model type uncertainty range\n",
    "GS_Data1_Total_Max = GS1_MaxScaler_Image.select('PotentialTotal').addBands(GS1_MeanScaler_Image.select('PotentialTotal')).reduce(ee.Reducer.max())\n",
    "GS_Data1_Total_Min = GS1_MaxScaler_Image.select('PotentialTotal').addBands(GS1_MeanScaler_Image.select('PotentialTotal')).reduce(ee.Reducer.min())\n",
    "GS_Data1_Total_Range = GS_Data1_Total_Max.subtract(GS_Data1_Total_Min)\n",
    "\n",
    "GS_Data2_Total_Max = GS2_MaxScaler_Image.select('PotentialTotal').addBands(GS2_MeanScaler_Image.select('PotentialTotal')).reduce(ee.Reducer.max())\n",
    "GS_Data2_Total_Min = GS2_MaxScaler_Image.select('PotentialTotal').addBands(GS2_MeanScaler_Image.select('PotentialTotal')).reduce(ee.Reducer.min())\n",
    "GS_Data2_Total_Range = GS_Data2_Total_Max.subtract(GS_Data2_Total_Min)\n",
    "\n",
    "GS_Data_Total_Range = GS_Data1_Total_Range.add(GS_Data2_Total_Range).divide(2)\n",
    "\n",
    "\n",
    "RM_Data1_Total_Max = HM1_Image.select('PotentialTotal').addBands(SD1_Image.select('PotentialTotal')).addBands(WK1_Image.select('PotentialTotal')).reduce(ee.Reducer.max())\n",
    "RM_Data1_Total_Min = HM1_Image.select('PotentialTotal').addBands(SD1_Image.select('PotentialTotal')).addBands(WK1_Image.select('PotentialTotal')).reduce(ee.Reducer.min())\n",
    "RM_Data1_Total_Range = RM_Data1_Total_Max.subtract(RM_Data1_Total_Min)\n",
    "\n",
    "RM_Data2_Total_Max = HM2_Image.select('PotentialTotal').addBands(SD2_Image.select('PotentialTotal')).addBands(WK2_Image.select('PotentialTotal')).reduce(ee.Reducer.max())\n",
    "RM_Data2_Total_Min = HM2_Image.select('PotentialTotal').addBands(SD2_Image.select('PotentialTotal')).addBands(WK2_Image.select('PotentialTotal')).reduce(ee.Reducer.min())\n",
    "RM_Data2_Total_Range = RM_Data2_Total_Max.subtract(RM_Data2_Total_Min)\n",
    "\n",
    "RM_Data_Total_Range = RM_Data1_Total_Range.add(RM_Data2_Total_Range).divide(2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "fullRangeGS = GS_Data_Total_Range.add(GS_Model_Range).add(Soil_Range).add(GS_Litter_Range).add(GS_Root_Range).add(GS_AGB_Range)\n",
    "# GS uncertainty contribution\n",
    "contributionImageGS = GS_Data_Total_Range.addBands(GS_Model_Range).addBands(Soil_Range).addBands(GS_Litter_Range).addBands(GS_Root_Range).addBands(GS_AGB_Range).divide(fullRangeGS).rename(['Data','Model','Soil','Litter','Root','AGB'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [],
   "source": [
    "fullRangeRM = RM_Data_Total_Range.add(RM_Model_Range).add(Soil_Range).add(RM_Litter_Range).add(RM_Root_Range).add(RM_AGB_Range)\n",
    "# RM uncertainty contribution\n",
    "contributionImageRM =  RM_Data_Total_Range.addBands(RM_Model_Range).addBands(Soil_Range).addBands(RM_Litter_Range).addBands(RM_Root_Range).addBands(RM_AGB_Range).divide(fullRangeRM).rename(['Data','Model','Soil','Litter','Root','AGB'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'state': 'READY',\n",
       " 'description': 'GS_Uncertainty_Contribution_Maps_Export',\n",
       " 'creation_timestamp_ms': 1690818102463,\n",
       " 'update_timestamp_ms': 1690818102463,\n",
       " 'start_timestamp_ms': 0,\n",
       " 'task_type': 'EXPORT_IMAGE',\n",
       " 'id': 'TP57UZLSREOUMVUTSVDPSVAP',\n",
       " 'name': 'projects/earthengine-legacy/operations/TP57UZLSREOUMVUTSVDPSVAP'}"
      ]
     },
     "execution_count": 60,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exportGS_Uncertainty = ee.batch.Export.image.toAsset(image = contributionImageGS,\n",
    "                                               description = 'GS_Uncertainty_Contribution_Maps_Export',\n",
    "                                               assetId = 'users/leonidmoore/ForestBiomass/UncertaintyFigure/GS_Uncertainty_contribution_Maps',\n",
    "                                               region = unboundedGeo,\n",
    "                                               crs = 'EPSG:4326',\n",
    "                                               crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                               maxPixels = 1e13)\n",
    "# start the export task\n",
    "exportGS_Uncertainty.start()\n",
    "# show the task status\n",
    "exportGS_Uncertainty.status()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'state': 'READY',\n",
       " 'description': 'RM_Uncertainty_Contribution_Maps_Export',\n",
       " 'creation_timestamp_ms': 1690818103944,\n",
       " 'update_timestamp_ms': 1690818103944,\n",
       " 'start_timestamp_ms': 0,\n",
       " 'task_type': 'EXPORT_IMAGE',\n",
       " 'id': 'JYCK7XHJUZUCFV2LN3RSIEIY',\n",
       " 'name': 'projects/earthengine-legacy/operations/JYCK7XHJUZUCFV2LN3RSIEIY'}"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "exportRM_Uncertainty = ee.batch.Export.image.toAsset(image = contributionImageRM,\n",
    "                                               description = 'RM_Uncertainty_Contribution_Maps_Export',\n",
    "                                               assetId = 'users/leonidmoore/ForestBiomass/UncertaintyFigure/RM_Uncertainty_contribution_Maps',\n",
    "                                               region = unboundedGeo,\n",
    "                                               crs = 'EPSG:4326',\n",
    "                                               crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                               maxPixels = 1e13)\n",
    "# start the export task\n",
    "exportRM_Uncertainty.start()\n",
    "# show the task status\n",
    "exportRM_Uncertainty.status()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4 Export the top two maximum "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.1 Export for the Satellite-derived model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Model', 'Data', 'AGB', 'Root', 'Litter', 'Soil']\n",
      "['0_constant', '1_constant', '2_constant', '3_constant', '4_constant', '5_constant']\n",
      "['SecondMax', 'FirstMax']\n"
     ]
    }
   ],
   "source": [
    "# refer to the code in GEE accout '20230802_variance_explained_by_different_parts'\n",
    "\n",
    "\n",
    "# load the image with the contribution of the variance from all sources\n",
    "rawImage = ee.Image(\"users/leonidmoore/ForestBiomass/UncertaintyFigure/RM_Uncertainty_contribution_Maps\");\n",
    "# re-sort the image by the band names with alphabetical order\n",
    "varianceImage = rawImage.select([\"Model\",\"Data\",\"AGB\",\"Root\",\"Litter\",\"Soil\"]);\n",
    "# print the new band names\n",
    "print(varianceImage.bandNames().getInfo())\n",
    "# transfer the image into array\n",
    "arrayImage = varianceImage.toArray()\n",
    "# sort them by the values in a ascending way(default in GEE)\n",
    "sortedArrayImage = arrayImage.arraySort()\n",
    "# slice the array to the get top two values\n",
    "maxValImageRM = sortedArrayImage.arraySlice(0,-2).arrayFlatten([[\"SecondMax\",\"FirstMax\"]])\n",
    "\n",
    "# now let's export the correpoding IDs for the max and second mas value\n",
    "# generate a multi-band image with the order index which will be used for pointing at the relavant sources\n",
    "def bandfunc(bandOrder):\n",
    "    return ee.Image.constant (bandOrder)\n",
    "\n",
    "idImage = ee.ImageCollection(ee.List.sequence(0,rawImage.bandNames().length().subtract(1)).map(bandfunc)).toBands()\n",
    "print(idImage.bandNames().getInfo())\n",
    "# sort the idImage by the value of the array image\n",
    "sortedArrayImage = idImage.toArray().arraySort(arrayImage)\n",
    "maxValID_ImageRM = sortedArrayImage.arraySlice(0,-2).arrayFlatten([[\"SecondMax\",\"FirstMax\"]]);\n",
    "print(maxValID_Image.bandNames().getInfo())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'state': 'READY',\n",
       " 'description': 'RM_maxID_Image_Map_Export',\n",
       " 'creation_timestamp_ms': 1691007745739,\n",
       " 'update_timestamp_ms': 1691007745739,\n",
       " 'start_timestamp_ms': 0,\n",
       " 'task_type': 'EXPORT_IMAGE',\n",
       " 'id': 'ENJZZWGY4GLJVHNAIPD4AOAF',\n",
       " 'name': 'projects/earthengine-legacy/operations/ENJZZWGY4GLJVHNAIPD4AOAF'}"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# export the maps into google cloud storage\n",
    "exportVarianceValue = ee.batch.Export.image.toCloudStorage(image = maxValImageRM,\n",
    "                                                           description = 'RM_maxValImage_Map_Export',\n",
    "                                                           fileNamePrefix = 'ForestBiomassVariance/RM_max_variance_values_map',\n",
    "                                                           region = unboundedGeo,\n",
    "                                                           bucket = \"crowtherlab_gcsb_lidong\",\n",
    "                                                           crs = 'EPSG:4326',\n",
    "                                                           crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                                           maxPixels = 1e13,\n",
    "                                                           fileFormat = 'GeoTIFF')\n",
    "# start the export task\n",
    "exportVarianceValue.start()\n",
    "# show the task status\n",
    "exportVarianceValue.status()\n",
    "\n",
    "# export the maps into google cloud storage\n",
    "exportVarianceID = ee.batch.Export.image.toCloudStorage(image = maxValID_ImageRM,\n",
    "                                                        description = 'RM_maxID_Image_Map_Export',\n",
    "                                                        fileNamePrefix = 'ForestBiomassVariance/RM_max_variance_IDs_map',\n",
    "                                                        region = unboundedGeo,\n",
    "                                                        bucket = \"crowtherlab_gcsb_lidong\",\n",
    "                                                        crs = 'EPSG:4326',\n",
    "                                                        crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                                        maxPixels = 1e13,\n",
    "                                                        fileFormat = 'GeoTIFF')\n",
    "# start the export task\n",
    "exportVarianceID.start()\n",
    "# show the task status\n",
    "exportVarianceID.status()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 4.2 Export for the Ground-sourced model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Model', 'Data', 'AGB', 'Root', 'Litter', 'Soil']\n",
      "['0_constant', '1_constant', '2_constant', '3_constant', '4_constant', '5_constant']\n",
      "['SecondMax', 'FirstMax']\n"
     ]
    }
   ],
   "source": [
    "# refer to the code in GEE accout '20230802_variance_explained_by_different_parts'\n",
    "\n",
    "\n",
    "# load the image with the contribution of the variance from all sources\n",
    "rawImage = ee.Image(\"users/leonidmoore/ForestBiomass/UncertaintyFigure/GS_Uncertainty_contribution_Maps\");\n",
    "# re-sort the image by the band names with alphabetical order\n",
    "varianceImage = rawImage.select([\"Model\",\"Data\",\"AGB\",\"Root\",\"Litter\",\"Soil\"]);\n",
    "# print the new band names\n",
    "print(varianceImage.bandNames().getInfo())\n",
    "# transfer the image into array\n",
    "arrayImage = varianceImage.toArray()\n",
    "# sort them by the values in a ascending way(default in GEE)\n",
    "sortedArrayImage = arrayImage.arraySort()\n",
    "# slice the array to the get top two values\n",
    "maxValImageGS = sortedArrayImage.arraySlice(0,-2).arrayFlatten([[\"SecondMax\",\"FirstMax\"]])\n",
    "\n",
    "# now let's export the correpoding IDs for the max and second mas value\n",
    "# generate a multi-band image with the order index which will be used for pointing at the relavant sources\n",
    "def bandfunc(bandOrder):\n",
    "    return ee.Image.constant (bandOrder)\n",
    "\n",
    "idImage = ee.ImageCollection(ee.List.sequence(0,rawImage.bandNames().length().subtract(1)).map(bandfunc)).toBands()\n",
    "print(idImage.bandNames().getInfo())\n",
    "# sort the idImage by the value of the array image\n",
    "sortedArrayImage = idImage.toArray().arraySort(arrayImage)\n",
    "maxValID_ImageGS = sortedArrayImage.arraySlice(0,-2).arrayFlatten([[\"SecondMax\",\"FirstMax\"]]);\n",
    "print(maxValID_Image.bandNames().getInfo())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'state': 'READY',\n",
       " 'description': 'GS_maxID_Image_Map_Export',\n",
       " 'creation_timestamp_ms': 1691007749371,\n",
       " 'update_timestamp_ms': 1691007749371,\n",
       " 'start_timestamp_ms': 0,\n",
       " 'task_type': 'EXPORT_IMAGE',\n",
       " 'id': '2LEAKXZV3N2CS3X756AXYLEB',\n",
       " 'name': 'projects/earthengine-legacy/operations/2LEAKXZV3N2CS3X756AXYLEB'}"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# export the maps into google cloud storage\n",
    "exportVarianceValue = ee.batch.Export.image.toCloudStorage(image = maxValImageGS,\n",
    "                                                           description = 'GS_maxValImage_Map_Export',\n",
    "                                                           fileNamePrefix = 'ForestBiomassVariance/GS_max_variance_values_map',\n",
    "                                                           region = unboundedGeo,\n",
    "                                                           bucket = \"crowtherlab_gcsb_lidong\",\n",
    "                                                           crs = 'EPSG:4326',\n",
    "                                                           crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                                           maxPixels = 1e13,\n",
    "                                                           fileFormat = 'GeoTIFF')\n",
    "# start the export task\n",
    "exportVarianceValue.start()\n",
    "# show the task status\n",
    "exportVarianceValue.status()\n",
    "\n",
    "# export the maps into google cloud storage\n",
    "exportVarianceID = ee.batch.Export.image.toCloudStorage(image = maxValID_ImageGS,\n",
    "                                                        description = 'GS_maxID_Image_Map_Export',\n",
    "                                                        fileNamePrefix = 'ForestBiomassVariance/GS_max_variance_IDs_map',\n",
    "                                                        region = unboundedGeo,\n",
    "                                                        bucket = \"crowtherlab_gcsb_lidong\",\n",
    "                                                        crs = 'EPSG:4326',\n",
    "                                                        crsTransform = [0.008333333333333333,0,-180,0,-0.008333333333333333,90],\n",
    "                                                        maxPixels = 1e13,\n",
    "                                                        fileFormat = 'GeoTIFF')\n",
    "# start the export task\n",
    "exportVarianceID.start()\n",
    "# show the task status\n",
    "exportVarianceID.status()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
